package com.gitee.tje.waving.aop;

import com.gitee.tje.waving.exception.WavingException;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.concurrent.Callable;

/**
 * method运行工具
 *
 * @author taojiaen
 * @date 2018-02-19 21:20
 */
public class MethodProcess {
    public final Method method;
    public final Object[] args;
    public final Object target;
    public final Callable callable;
    public final List<MethodHook> methodHookList;
    private int index = -1;


    public MethodProcess(Method method, Object[] args, Object target,
                         List<MethodHook> methodHookList) {
        this.method = method;
        this.args = args;
        this.target = target;
        this.methodHookList = methodHookList;
        this.callable = () -> {
            try {
                return  method.invoke(this.target, args);
            } catch (IllegalAccessException | IllegalArgumentException e) {
                throw e;
            } catch (InvocationTargetException e) {
                if (e.getCause() instanceof  Exception) {
                    throw (Exception) e.getCause();
                }else {
                    throw e;
                }
            }
        };
    }

    public Object process() {
        ++index;
        if (methodHookList == null || index >= methodHookList.size()) {
            try {
                return callable.call();
            } catch (RuntimeException e) {
                throw e;
            }catch (Exception e) {
                throw new WavingException(e);
            }
        }
        return methodHookList.get(index).process(this);
    }
}
